import 'dart:core';

import 'package:osc/common/regex_constants.dart';

/// <pre>
/// desc  : 正则相关工具类
/// </pre>
class RegexUtil {

  /// 验证手机号（简单）
  /// @param input 待验证文本
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isMobileSimple(final String input) {
    return isMatch(RegexConstants.REGEX_MOBILE_SIMPLE, input);
  }

  /// 验证手机号（精确）
  /// @param input 待验证文本
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isMobileExact(final String input) {
    return isMatch(RegexConstants.REGEX_MOBILE_EXACT, input);
  }

  /// 验证电话号码
  /// @param input 待验证文本
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isTel(final String input) {
    return isMatch(RegexConstants.REGEX_TEL, input);
  }

  /// 验证身份证号码15位
  /// @param input 待验证文本
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isIDCard15(final String input) {
    return isMatch(RegexConstants.REGEX_ID_CARD15, input);
  }

  /// 验证身份证号码18位
  /// @param input 待验证文本
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isIDCard18(final String input) {
    return isMatch(RegexConstants.REGEX_ID_CARD18, input);
  }

  /// 验证邮箱
  /// @param input 待验证文本
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isEmail(final String input) {
    return isMatch(RegexConstants.REGEX_EMAIL, input);
  }

  /// 验证URL
  /// @param input 待验证文本
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isURL(final String input) {
    return isMatch(RegexConstants.REGEX_URL, input);
  }

  /// 验证URL_PREFIX
  /// @param input 待验证文本
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isURLPrefix(final String input) {
    return isMatch(RegexConstants.REGEX_URL_PREFIX, input);
  }

  /// 验证汉字
  /// @param input 待验证文本
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isZh(final String input) {
    return isMatch(RegexConstants.REGEX_ZH, input);
  }

  /// 验证用户名
  /// <p>取值范围为a-z,A-Z,0-9,"_",汉字，不能以"_"结尾,用户名必须是6-20位</p>
  /// @param input 待验证文本
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isUsername(final String input) {
    return isMatch(RegexConstants.REGEX_USERNAME, input);
  }

  /// 验证yyyy-MM-dd格式的日期校验，已考虑平闰年
  /// @param input 待验证文本
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isDate(final String input) {
    return isMatch(RegexConstants.REGEX_DATE, input);
  }

  /// 验证IP地址
  /// @param input 待验证文本
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isIP(final String input) {
    return isMatch(RegexConstants.REGEX_IP, input);
  }

  /// 判断是否匹配正则
  /// @param regex 正则表达式
  /// @param input 要匹配的字符串
  /// @return {@code true}: 匹配<br>{@code false}: 不匹配
  static bool isMatch(final String regex, final String input) {
    bool isMatch = false;
    if(input != null && input.isNotEmpty){
      RegExp regExp = new RegExp(regex);
      isMatch = regExp.hasMatch(input);
    }
    return isMatch;
  }

  /// 获取正则匹配的部分
  /// @param regex 正则表达式
  /// @param input 要匹配的字符串
  /// @return 正则匹配的部分
  static List<String> getMatches(final String regex, final String input) {
    if (input == null) return null;
    List<String> matches = new List<String>();
    RegExp regExp = new RegExp(regex);
    Iterable<Match> strings = regExp.allMatches(input);
    for(Match m in strings){
      matches.add(m.group(0));
    }
    return matches;
  }

  /// 获取正则匹配分组
  /// @param input 要分组的字符串
  /// @param regex 正则表达式
  /// @return 正则匹配分组
  /*static String[] getSplits(final String input, final String regex) {
    if (input == null) return null;
    return input.split(regex);
  }*/

  /// 替换正则匹配的第一部分
  /// @param input       要替换的字符串
  /// @param regex       正则表达式
  /// @param replacement 代替者
  /// @return 替换正则匹配的第一部分
  static String getReplaceFirst(final String input, final String regex, final String replacement) {
    if (input == null) return null;
    RegExp regExp = new RegExp(regex);
    if(regExp.hasMatch(input)){
      return regExp.stringMatch(input).replaceFirst(RegExp(regex), replacement);
    } else{
      return null;
    }
//    return Pattern.compile(regex).matcher(input).replaceFirst(replacement);
  }

  /// 替换所有正则匹配的部分
  /// @param input       要替换的字符串
  /// @param regex       正则表达式
  /// @param replacement 代替者
  /// @return 替换所有正则匹配的部分
  static String getReplaceAll(final String input, final String regex, final String replacement) {
    if (input == null) return null;
    RegExp regExp = new RegExp(regex);
    Iterable<Match> strings = regExp.allMatches(input);
    for(Match m in strings){
      for(int i = 0; i < m.groupCount; i++){
        m.group(i).replaceAll(input, replacement);
      }
    }
    return regExp.stringMatch(input).replaceAll(RegExp(regex), replacement);
//    return Pattern.compile(regex).matcher(input).replaceAll(replacement);
  }

  static bool isPassword(final String input){
    return isMatch(RegexConstants.REGEX_PASSWORD, input);
  }

  static bool isBankCardNumber(final String input){
    return isMatch(RegexConstants.REGEX_BANK_CARD, input);
  }

  /// 获取指定HTML标签的指定属性的值
  /// @param source 要匹配的源文本
  /// @param element 标签名称
  /// @param attr 标签的属性名称
  /// @return 属性值列表
  static List<String> getAttrValuesFromHtmlTag(String source, String element, String attr) {
    List<String> result = new List<String>();
    //"<" + ".*" + "[^<>]*?\\s?>(.*?)"
    // *	匹配前面的子表达式零次或多次。
    // +	匹配前面的子表达式一次或多次。
    // ?	匹配前面的子表达式零次或一次。
    // .	匹配除换行符 \n 之外的任何单字符
    // \s 匹配任何空白字符，包括空格、制表符、换页符等等。
    // ()	标记一个子表达式的开始和结束位置。
    String regex = "<" + element + "[^<>]*?\\s" + attr + "=['\"]?(.*?)['\"]?(\\s.*)?>";
//    String regex = "<" + element + "[^<>]*?\\s" + attr + "=['\"]?(.*?)['\"]>";
    RegExp regExp = new RegExp(regex);
    Iterable<Match> strings = regExp.allMatches(source);
    for(Match m in strings){
      result.add(m.group(1));
    }
    return result;
  }
  static String getAttrValueFromHtmlTag(String source, String element, String attr) {
    String result;
    List<String> list = getAttrValuesFromHtmlTag(source, element, attr);
    if(list.isNotEmpty){
      result = list[0];
    }
    return result;
  }


  /// source xxxx<xxx>xxxxx</xxx>xxx
  /// return [<xxx>xxxx</xxx>,<xxx>xxxx</xxx>,...]
  static List<String> getStringListFromHtmlTag(String source, String element, {int group = 1}){
    List<String> result = new List<String>();
    String regex = "<" + element + "[^<>]*?\\s?>(.*?)</" + element + ">";
    RegExp regExp = new RegExp(regex);
    Iterable<Match> strings = regExp.allMatches(source);
    for(Match m in strings){
      result.add(m.group(group));
    }
    return result;
  }

  /// source xxxx<xxx>xxxxx</xxx>xxx
  /// return <xxx>xxxx</xxx>
  static String getStringFromHtmlTag(String source, String element){
    String result;
    String regex = "<" + element + "[^<>]*?\\s?>(.*?)</" + element + ">";
    RegExp regExp = new RegExp(regex);
    Iterable<Match> strings = regExp.allMatches(source);
    for(Match m in strings){
      result = m.group(0);
      break;
    }
    return result;
  }

  static List<String> getStringListFromContent(String source, String startElement, String endElement, int group){
    List<String> result = new List<String>();
    String regex = startElement + "[^" + startElement + "]*?\\s?(.*?)" + endElement;
    RegExp regExp = new RegExp(regex);
    Iterable<Match> strings = regExp.allMatches(source);
    for(Match m in strings){
      result.add(m.group(group));
    }
    return result;
  }

  /// xxxxxxxxxxxxxxxxxx
  /// startElement
  /// endElement
  /// return startElement + xxxxxx + endElement
  static String getStringFromContent(String source, String startElement, String endElement){
    String result;
    String regex = startElement + "[^" + startElement + "]*?\\s?(.*?)" + endElement;
    RegExp regExp = new RegExp(regex);
    while (regExp.hasMatch(source)){
      result = regExp.stringMatch(source);
      break;
    }
    return result;
  }

  static List<String> getNumberFromString(String source, String startElement, String endElement, int group){
    List<String> result = new List<String>();
    String regex = RegexConstants.REGEX_TENCENT_NUM;
    RegExp regExp = new RegExp(regex);
    Iterable<Match> strings = regExp.allMatches(source);
    for(Match m in strings){
      result.add(m.group(group));
    }
    return result;
  }
}
